<template>
	<view class="upload-attachments">
		<view class="upload-header">
			<text class="form-label">{{ label }}</text>
			<view class="upload-button" @tap="chooseFile" v-if="!disabled">
				<text class="upload-icon">+</text>
			</view>
		</view>
		<view class="upload-section">
			<view class="upload-list" v-if="fileList.length > 0">
				<view class="upload-item-file" v-for="(file, index) in fileList" :key="index">
					<image class="file-icon" :src="getFileUrl(file)" mode="aspectFit" @tap="previewFile(file)"></image>
					<text class="file-name">{{ file.name }}</text>
					<text class="file-size">{{ file.size }}</text>
					<text class="file-delete" @tap="removeFile(index)" v-if="!disabled">×</text>
				</view>
			</view>
			<view class="upload-tips" v-if="fileList.length === 0">
				<text class="tips-text">支持 jpg、jpeg、png 格式，单个文件不超过10MB</text>
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { formatFileSize } from '@/common/upload'
import config from '@/common/config'

// 定义组件属性
interface Props {
	modelValue?: any[]
	label?: string
	disabled?: boolean
	maxCount?: number
	fileTypes?: string[]
}

const props = withDefaults(defineProps<Props>(), {
	modelValue: () => [],
	label: '上传附件',
	disabled: false,
	maxCount: 5,
	fileTypes: () => ['jpg', 'jpeg', 'png']
})

// 定义事件
const emit = defineEmits<{
	'update:modelValue': [files: any[]]
	'change': [files: any[]]
}>()

// 内部文件列表
const fileList = ref<any[]>([])

// 获取文件URL
const getFileUrl = (file: any): string => {
	if (!file || !file.url) {
		return ''
	}
	// 如果是完整的URL，直接返回
	if (file.url.startsWith('http://') || file.url.startsWith('https://')) {
		return file.url
	}
	// 如果是相对路径，添加基础URL
	return config.baseUrl + file.url
}

// 同步外部数据到内部
const syncFromExternal = () => {
	if (props.modelValue && Array.isArray(props.modelValue)) {
		fileList.value = [...props.modelValue]
	}
}

// 同步内部数据到外部
const syncToExternal = () => {
	emit('update:modelValue', [...fileList.value])
	emit('change', [...fileList.value])
}

// 监听 modelValue 变化
watch(() => props.modelValue, (newValue: any[]) => {
	console.log('UploadAttachments 接收到新的 modelValue:', newValue)
	if (newValue && Array.isArray(newValue)) {
		fileList.value = [...newValue]
		console.log('UploadAttachments 更新 fileList:', fileList.value)
	} else {
		fileList.value = []
		console.log('UploadAttachments 重置 fileList 为空数组')
	}
}, { deep: true, immediate: true })

// 初始化时同步数据
syncFromExternal()

// 选择文件
const chooseFile = () => {
	if (props.disabled) return	
			if (fileList.value.length >= props.maxCount) {
			uni.showToast({
				title: `最多只能上传${props.maxCount}个文件`,
				icon: 'none'
			})
			return
		}

		// 显示选择提示
		uni.showToast({
			title: '请选择图片文件',
			icon: 'none',
			duration: 1000
		})

	uni.chooseImage({
		count: props.maxCount - fileList.value.length,
		sourceType: ['album', 'camera'],
		sizeType: ['compressed'], // 使用压缩图片，减少文件大小
		extension: props.fileTypes,
		success: (res: any) => {
			// 处理选择的图片文件
			res.tempFilePaths.forEach((filePath: string, index: number) => {
				const extension = filePath.toLowerCase().split('.').pop()
				const fileName = `附件${fileList.value.length + index + 1}.${extension}`
				// 获取文件信息
				uni.getFileSystemManager().getFileInfo({
					filePath: filePath,
					success: (fileInfo: any) => {
						// 检查文件大小（微信小程序限制单个文件不超过10MB）
						const maxSize = 10 * 1024 * 1024 // 10MB
						if (fileInfo.size > maxSize) {
							uni.showToast({
								title: '文件大小不能超过10MB',
								icon: 'none'
							})
							return
						}

						const newFile = {
							name: fileName,
							url: filePath,
							path: filePath,
							size: formatFileSize(fileInfo.size),
							type: extension
						}
						fileList.value.push(newFile)
						syncToExternal()
					},
					fail: (error: any) => {
						console.error('获取文件信息失败:', error)
						const newFile = {
							name: fileName,
							url: filePath,
							path: filePath,
							size: '未知大小',
							type: extension
						}
						fileList.value.push(newFile)
						syncToExternal()
					}
				})
			})
		},
		fail: (error: any) => {
			// 用户取消选择时不显示提示
			if (error.errMsg && error.errMsg.includes('cancel')) {
				console.log('用户取消选择图片')
				return
			}
			
			console.error('选择图片失败:', error)
			uni.showToast({
				title: '选择图片失败',
				icon: 'none'
			})
		}
	})
}

// 预览文件
const previewFile = (file: any) => {
	if (!file || !file.url) {
		uni.showToast({
			title: '文件地址无效',
			icon: 'none'
		})
		return
	}

	const fileUrl = getFileUrl(file)
	
	// 预览图片
	uni.previewImage({
		urls: [fileUrl],
		current: fileUrl
	})
}

// 删除文件
const removeFile = (index: number) => {
	if (props.disabled) return
	fileList.value.splice(index, 1)
	syncToExternal()
}

// 清空文件列表
const clearFiles = () => {
	fileList.value = []
	syncToExternal()
}

// 获取文件列表
const getFiles = () => {
	return fileList.value
}

// 暴露方法给父组件
defineExpose({
	clearFiles,
	getFiles
})
</script>

<style scoped>
.upload-attachments {
	width: 100%;
}

.upload-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 16rpx;
}

.form-label {
	font-size: 28rpx;
	color: #333;
	font-weight: bold;
}

.upload-button {
	width: 60rpx;
	height: 60rpx;
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
	transition: all 0.3s ease;
}

.upload-button:active {
	transform: scale(0.95);
	box-shadow: 0 2rpx 8rpx rgba(102, 126, 234, 0.4);
}

.upload-icon {
	color: white;
	font-size: 32rpx;
	font-weight: bold;
}

.upload-section {
	width: 100%;
}

.upload-list {
	display: flex;
	flex-direction: column;
	gap: 12rpx;
}

.upload-item-file {
	display: flex;
	align-items: center;
	padding: 16rpx;
	background-color: #f8f9fa;
	border-radius: 8rpx;
	border: 1rpx solid #e9ecef;
	position: relative;
}

.file-icon {
	width: 60rpx;
	height: 60rpx;
	border-radius: 6rpx;
	margin-right: 12rpx;
	background-color: #e9ecef;
	cursor: pointer;
	transition: transform 0.2s ease;
}

.file-icon:active {
	transform: scale(0.95);
}

.file-name {
	flex: 1;
	font-size: 26rpx;
	color: #333;
	margin-right: 8rpx;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.file-size {
	font-size: 24rpx;
	color: #666;
	margin-right: 12rpx;
}

.file-delete {
	width: 40rpx;
	height: 40rpx;
	background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
	color: white;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 24rpx;
	font-weight: bold;
	box-shadow: 0 2rpx 8rpx rgba(255, 107, 107, 0.3);
	transition: all 0.3s ease;
}

.file-delete:active {
	transform: scale(0.9);
	box-shadow: 0 1rpx 4rpx rgba(255, 107, 107, 0.4);
}

.upload-tips {
	margin-top: 16rpx;
	padding: 12rpx 16rpx;
	background-color: #f8f9fa;
	border-radius: 6rpx;
	border: 1rpx solid #e9ecef;
}

.tips-text {
	font-size: 24rpx;
	color: #666;
	line-height: 1.4;
}
</style> 